﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;

namespace ViewComponents.Behaviours
{
    public static class FocusBehaviour
    {
        public static bool GetIsFocused(DependencyObject obj)
        {
            return (bool)obj.GetValue(IsFocusedProperty);
        }

        public static void SetIsFocused(DependencyObject obj, bool value)
        {
            obj.SetValue(IsFocusedProperty, value);
        }

        public static readonly DependencyProperty IsFocusedProperty =
                DependencyProperty.RegisterAttached("IsFocused", typeof(bool), typeof(FocusBehaviour),
                 new UIPropertyMetadata(false, OnIsFocusedPropertyChanged));


        static void OnIsFocusedPropertyChanged(DependencyObject obj,
                DependencyPropertyChangedEventArgs e)
        {
            UIElement element = (UIElement)obj;
            if ((bool)e.NewValue)
            {
                element.Focus();
                if (element is Selector)
                    FocusOnSelectedItem((Selector)element);
                element.LostFocus += new RoutedEventHandler(element_LostFocus);
            }
        }

        static void element_LostFocus(object sender, RoutedEventArgs e)
        {
            UIElement element = (UIElement)sender;
            SetIsFocused(element, false);
            element.LostFocus -= new RoutedEventHandler(element_LostFocus);
        }

        static void FocusOnSelectedItem(Selector selector)
        {
            if (selector.SelectedItem != null)
            {
                selector.Dispatcher.BeginInvoke(new Action(() =>
                {
                    UIElement item = selector.ItemContainerGenerator.ContainerFromItem(selector.SelectedItem) as UIElement;
                    if (item != null)
                        item.Focus();
                }), System.Windows.Threading.DispatcherPriority.Input);
            }
        }
    }
}
